package com.hq.zb.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.hq.zb.dto.UserDto;
import com.hq.zb.entity.CurrentUser;
import com.hq.zb.exception.BizException;
import com.hq.zb.exception.BizExceptionEnum;
import com.hq.zb.model.User;
import com.hq.zb.service.IRoleUserService;
import com.hq.zb.service.IUserService;
import com.hq.zb.utils.AuthResult;
import com.hq.zb.utils.BCryptUtils;
import com.hq.zb.utils.JWTUtil;
import com.hq.zb.utils.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 登录Controller
 * @author huanghanrui
 * @date 2022-03-23
 */
@Api(tags = "登录")
@RestController
@RequestMapping("/auth")
public class LoginController {
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleUserService roleUserService;

    /**
     * 登录认证
     *
     * @param user 登陆参数
     */
    @ApiOperation(value = "登录服务")
    @PostMapping("/login")
    public AuthResult login(@RequestBody UserDto user, HttpServletResponse response) {
        //验证用户名
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.eq("delete_flag", false);
        wrapper.like("user_name", user.getUserName());
        List<User> userDtoList = userService.selectList(wrapper);
        if (CollectionUtil.isEmpty(userDtoList)) {
            throw new BizException(BizExceptionEnum.INVALID_ARGUMENT, "用户名在系统中不存在");
        }
        CurrentUser currentUser = new CurrentUser();
        BeanUtil.copyProperties(userDtoList.get(0), currentUser);
        //if (!StringUtils.isEmpty(user.getUserName())){
        if (BCryptUtils.checkpw(user.getPassword(), currentUser.getPassword())) {
            //查询用户角色
            List<String> roleCodes = roleUserService.queryRoleName(user.getUserId());
            String roles = "";
            if (CollectionUtil.isNotEmpty(roleCodes)) {
                roles = org.apache.commons.lang.StringUtils.join(roleCodes, ",");
            }
            currentUser.setRoles(roles);
            //生成token
            String token = JWTUtil.generateToken(currentUser.getUserName(), roles);
            //生成refreshToken
            String refreshToken = UUID.randomUUID().toString().replace("-", "");
            RedisUtil.setBean(currentUser.getUserName(), currentUser);
            //数据放入redis
            redisTemplate.opsForHash().put(refreshToken, "token", token);
            redisTemplate.opsForHash().put(refreshToken, "username", currentUser.getUserName());
            redisTemplate.opsForHash().put(refreshToken, "roles", roles);
            //设置token的过期时间
            redisTemplate.expire(refreshToken, JWTUtil.REFRESH_TOKEN_EXPIRE_TIME, TimeUnit.MILLISECONDS);
            return new AuthResult(20000, "success", token, refreshToken);
        } else {
            throw new BizException(BizExceptionEnum.DATA_NOT_EXIST, "检查输入的账户名和密码是否正确");
        }
    }

    /**
     * 刷新token
     */
    @GetMapping("/refreshToken")
    public AuthResult refreshToken(@RequestParam String refreshToken) {
        String username = (String) redisTemplate.opsForHash().get(refreshToken, "username");
        String roles = (String) redisTemplate.opsForHash().get(refreshToken, "roles");
        if (StringUtils.isEmpty(username)) {
            return new AuthResult(1003, "refreshToken error");
        }

        //生成新的token
        String newToken = JWTUtil.generateToken(username, roles);
        redisTemplate.opsForHash().put(refreshToken, "token", newToken);
        return new AuthResult(0, "success", newToken, refreshToken);
    }

    @GetMapping("/")
    public String index() {
        return "auth-service: " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 注销退出登陆
     * @param refreshToken
     * @return
     */
    @GetMapping("/exit")
    public String exit(@RequestParam String refreshToken) {
        //删除缓存
        redisTemplate.delete(refreshToken);
        return "注销成功";
    }
}
